﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AutoMachine
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            //设置应用程序处理异常方式：ThreadException处理
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
            //处理UI线程异常
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
            //处理非UI线程异常
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);


            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            if (RunningInstance() == null)
            {
                if (Device.ConfigAll())
                {
                    //加载板卡
                    //Device.InitSyetem();
                     Application.Run(new Frm_Main());
                    //Device.DeinitSystem();

                }
            }
            else
            {
                HandleRunningInstance(RunningInstance());
            }



        }

        #region 在进程中查找是否已经有实例在运行,确保程序只运行一个实例

        [DllImport("User32.dll")]
        private static extern bool ShowWindowAsync(System.IntPtr hWnd, int cmdShow);
        [DllImport("User32.dll")]
        public static extern bool SetForegroundWindow(System.IntPtr hWnd);

        private static Process RunningInstance()
        {
            Process current = Process.GetCurrentProcess();
            Process[] processes = Process.GetProcessesByName(current.ProcessName);
            foreach (Process process in processes)//遍历与当前进程名称相同的进程列表
            {
                if (process.Id != current.Id)//如果实例已经存在则忽略当前进程 
                {
                    //保证要打开的进程同已经存在的进程来自同一文件路径
                    if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName)
                    {
                        return process;//返回已经存在的进程
                    }
                }
            }
            return null;
        }

        //已经有了就把它激活，并将其窗口放置最前端
        private static void HandleRunningInstance(Process instance)
        {
            ShowWindowAsync(instance.MainWindowHandle, 1); //调用api函数，正常显示窗口
            SetForegroundWindow(instance.MainWindowHandle);//将窗口放置最前端
        }

        #endregion

        /// <summary>
        /// 处理UI主线程异常
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            WriteLog("UI主线程异常 " + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + " Message：" + e.Exception.Message + " StackTrace：" + e.Exception.StackTrace);
            //此处可以弹出提示，退出程序       
            MessageBox.Show(e.Exception.ToString(), "系统错误1", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        /// <summary>
        /// 处理未捕获异常
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            WriteLog("未捕获的异常 " + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + " " + e.ExceptionObject.ToString());
            //此处可以弹出提示，退出程序
            MessageBox.Show(e.ExceptionObject.ToString(), "系统错误2", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        public static void WriteLog(string log)
        {
            string filePath = AppDomain.CurrentDomain.BaseDirectory + @"\ErrLog.log";
            using (FileStream fs = new FileStream(filePath, FileMode.Append))
            {
                using (StreamWriter sw = new StreamWriter(fs, Encoding.Default))
                {
                    sw.WriteLine(log);
                }
            }
        }

    }
}
